home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 17 / CU Amiga Magazine's Super CD-ROM 17 (1997)(EMAP Images)(GB)[!][issue 1997-12].iso / CUCD / Magazine / C_Tutorial / Part-4 / screen5.c < prev    next >
C/C++ Source or Header  |  1997-08-31  |  11KB  |  403 lines

  1. /* First, include our own supporting header files, i.e., clip.h */
  2. #include "clip.h"
  3.  
  4. #include<exec/libraries.h>
  5. #include<intuition/intuition.h>
  6. #include<utility/tagitem.h>
  7. #include<graphics/text.h>
  8. #include<graphics/rastport.h>
  9. #include<intuition/screens.h>
  10. #include<libraries/gadtools.h>
  11.  
  12. #include<string.h>
  13. #include<stdio.h>
  14.  
  15. #include<clib/exec_protos.h>
  16. #include<clib/graphics_protos.h>
  17. #include<clib/intuition_protos.h>
  18. #include<clib/gadtools_protos.h>
  19.  
  20. /* The library base global variables */
  21. /* (The different style of opening libraries requires these to be initialised to NULL) */
  22. struct Library* GfxBase = NULL;
  23. struct Library* IntuitionBase = NULL;
  24. struct Library* LayersBase = NULL;
  25. struct Library* GadToolsBase = NULL;
  26.  
  27. /* The global handle on the palette gadget */
  28. struct Gadget* palgad = NULL;
  29. /* Global record of foreground pen */
  30. UBYTE pen;
  31.  
  32. /* Need to give prototypes for our functions */
  33. void handleIDCMP(struct Window*);
  34. void setupWindow();
  35. void createWindow(struct Gadget*, struct Screen*, struct Menu*);
  36. int openLibs();
  37. void closeLibs();
  38. struct Menu* createMenuStrip(APTR);
  39. void setFgPen(struct Window*, int);
  40. void doGadgetUp(struct Window*, struct IntuiMessage*);
  41. int doMenuPick(struct Window*, struct IntuiMessage*);
  42.  
  43. /* Some constants for the position and size of our gadget */
  44. #define MYBUT_LEFT        (10)
  45. #define MYBUT_TOP            (5)
  46. #define MYBUT_WIDTH        (80)
  47. #define MYBUT_HEIGHT    (12)
  48. #define MYBUT_TEXT        "Next Pen"
  49. #define MYBUT_ID            (0)
  50.  
  51. #define MYPAL_LEFT        (170)
  52. #define MYPAL_TOP            (2)
  53. #define MYPAL_WIDTH        (109)
  54. #define MYPAL_HEIGHT    (19)
  55. #define MYPAL_TEXT        "Colour:"
  56. #define MYPAL_ID            (1)
  57. #define MYPAL_DEPTH        (4)
  58.  
  59. /* The top gap required around the gadgets */
  60. #define MYTOPGAP      (30)
  61.  
  62. /* The initial pen colour */
  63. #define MYINITPEN            (1)
  64.  
  65. /* The start of the program */
  66. void main()
  67. {
  68.     /* Use a different style of opening libraries... */
  69.     if(openLibs())
  70.     {
  71.         /* Now do the real work */
  72.         setupWindow();
  73.     }
  74.     /* Matched call to close libraries */
  75.     closeLibs();
  76. }
  77.  
  78. /* Try to open all the libraries -- return TRUE on success */
  79. int openLibs()
  80. {
  81.     if((GfxBase = OpenLibrary("graphics.library",37)) == NULL)
  82.     {
  83.         printf("Error: could not open graphics.library\n");
  84.         return FALSE;
  85.     }
  86.     if((IntuitionBase = OpenLibrary("intuition.library",37)) == NULL)
  87.     {
  88.         printf("Error: could not open intuition.library\n");
  89.         return FALSE;
  90.     }
  91.     if((LayersBase = OpenLibrary("layers.library",37)) == NULL)
  92.     {
  93.         printf("Error: could not open layers.library\n");
  94.         return FALSE;
  95.     }
  96.     if((GadToolsBase = OpenLibrary("gadtools.library",37)) == NULL)
  97.     {
  98.         printf("Error: could not open gadtools.library\n");
  99.         return FALSE;
  100.     }
  101.   return TRUE;
  102. }
  103.  
  104. /* Close any open library */
  105. void closeLibs()
  106. {
  107.     if(GadToolsBase)
  108.         CloseLibrary(GadToolsBase);
  109.     if(LayersBase)
  110.         CloseLibrary(LayersBase);
  111.     if(IntuitionBase)
  112.         CloseLibrary(IntuitionBase);
  113.     if(GfxBase)
  114.         CloseLibrary(GfxBase);
  115. }
  116.  
  117. /* Setup the window -- do the GadTools stuff */
  118. void setupWindow()
  119. {
  120.     struct Screen* scr;
  121.     UWORD pens[] = { ~0 };
  122.     /* Try to open a new screen with 16 colours (four bitplanes deep) */
  123.     if(scr = OpenScreenTags(NULL,
  124.                                                     SA_Depth,    4,
  125.                                                     /* Enable 3D look by specifying SA_Pens */
  126.                                                     SA_Pens,    pens,
  127.                                                     TAG_DONE))
  128.     {
  129.         APTR vinfo;
  130.         /* Get the visual info so GadTools can render the gadgets nicely */
  131.         if(vinfo = GetVisualInfo(scr, TAG_DONE))
  132.         {
  133.             /* We can initialise glist in its declaration */
  134.             struct Gadget* glist = NULL;
  135.             struct Gadget* gad;
  136.             int offtop, offleft;
  137.             struct NewGadget newgad;
  138.             /* Initialised structure declaration: describes 8pt Topaz font */
  139.             struct TextAttr topazFont = { "topaz.font", 8, 0, 0, };
  140.             /* Start a GadTools gadget list */
  141.             gad = CreateContext(&glist);
  142.             /* The offsets of our window borders */
  143.             offleft = scr->WBorLeft;
  144.             offtop = scr->WBorTop + (scr->Font->ta_YSize + 1);
  145.  
  146.             /* Setup our first gadget */
  147.             newgad.ng_TextAttr         = &topazFont;
  148.             newgad.ng_VisualInfo     = vinfo;
  149.             newgad.ng_LeftEdge         = MYBUT_LEFT + offleft;
  150.             newgad.ng_TopEdge         = MYBUT_TOP + offtop;
  151.             newgad.ng_Width             = MYBUT_WIDTH;
  152.             newgad.ng_Height             = MYBUT_HEIGHT;
  153.             newgad.ng_GadgetText    = MYBUT_TEXT;
  154.             newgad.ng_GadgetID        = MYBUT_ID;
  155.             newgad.ng_Flags                = 0;
  156.             /* Now create it and add it to our list */
  157.             gad = CreateGadget(BUTTON_KIND, gad, &newgad, TAG_END);
  158.  
  159.             /* Setup our second gadget */
  160.             /* (We can reuse newgad, and just change the different bits) */
  161.             newgad.ng_LeftEdge         = MYPAL_LEFT + offleft;
  162.             newgad.ng_TopEdge         = MYPAL_TOP + offtop;
  163.             newgad.ng_Width             = MYPAL_WIDTH;
  164.             newgad.ng_Height             = MYPAL_HEIGHT;
  165.             newgad.ng_GadgetText    = MYPAL_TEXT;
  166.             newgad.ng_GadgetID        = MYPAL_ID;
  167.             newgad.ng_Flags                = 0;
  168.             /* Now create it and add it to our list */
  169.             if(gad = CreateGadget(PALETTE_KIND, gad, &newgad,
  170.                                                         /* Initially selected pen */
  171.                                                         GTPA_Color, MYINITPEN,
  172.                                                         /* Depth: 2 to the power MYPAL_DEPTH colours */
  173.                                                         GTPA_Depth, MYPAL_DEPTH,
  174.                                                         /* Gadget will indicate selection */
  175.                                                         GTPA_IndicatorWidth, 16,
  176.                                                         TAG_DONE))
  177.             {
  178.                 struct Menu* menustrip;
  179.                 /* Remember gadget pointer so we can affect it in message handler */
  180.                 palgad = gad;
  181.                 if(menustrip = createMenuStrip(vinfo))
  182.                     /* If succeeded then all gadgets and menus created */
  183.                     createWindow(glist, scr, menustrip);
  184.                 FreeMenus(menustrip);
  185.             }
  186.             else
  187.                 printf("Error: could not create gadget(s)\n");
  188.             /* Free all the gadgets that were created */
  189.             FreeGadgets(glist);
  190.             FreeVisualInfo(vinfo);
  191.         }
  192.         else
  193.             printf("Error: could not get visual info\n");
  194.         CloseScreen(scr);
  195.     }
  196.     else
  197.         printf("Error: could not create screen\n");
  198. }
  199.  
  200. /* Create the menu strip, using GadTools menu functions */
  201. struct Menu* createMenuStrip(APTR vinfo)
  202. {
  203.     /* The description of our menus */
  204.     struct NewMenu mymenu[] =
  205.     {
  206.         { NM_TITLE, "Project",        0,            0, 0, 0,},
  207.         {  NM_ITEM,        "Quit",                "Q",    0, 0, 0,},
  208.         { NM_TITLE, "Pen",                0,            0, 0, 0,},
  209.         {  NM_ITEM,        "Next",                "N",    0, 0, 0,},
  210.         {  NM_ITEM,        "Prev",                "P",    0, 0, 0,},
  211.         {  NM_ITEM,        NM_BARLABEL,    0,        0, 0, 0,},
  212.         {  NM_ITEM,        "Reset",            "R",    0, 0, 0,},
  213.         {   NM_END, NULL,                    0,            0, 0, 0,},
  214.     };
  215.     struct Menu* menustrip;
  216.     if (menustrip = CreateMenus(mymenu, TAG_END))
  217.     {
  218.         if (LayoutMenus(menustrip, vinfo, TAG_END))
  219.             /* Succeeded, so return menu strip */
  220.             return menustrip;
  221.         else
  222.         {
  223.             /* Failed, so must deallocate before returning */
  224.             FreeMenus(menustrip);
  225.             printf("Error: could not layout menus\n");
  226.         }
  227.     }
  228.     else
  229.         printf("Error: could not create menu strip\n");
  230.     /* Failed, so return NULL */
  231.     return NULL;
  232. }
  233.  
  234. /* Actually open the window, in the normal way */
  235. void createWindow(struct Gadget* glist, struct Screen* scr, struct Menu* menustrip)
  236. {
  237.     struct Window* win;
  238.     /* Open our window */
  239.     if(win = OpenWindowTags(NULL,
  240.                                                     WA_Left,                    0,
  241.                                                     WA_Top,                        0,
  242.                                                     /* Make the window the same size as the screen */
  243.                                                     WA_Width,                    scr->Width,
  244.                                                     WA_Height,                scr->Height,
  245.                                                     WA_Flags,                    WFLG_CLOSEGADGET | WFLG_DRAGBAR | WFLG_REPORTMOUSE,
  246.                                                     WA_IDCMP,                    IDCMP_CLOSEWINDOW | IDCMP_MOUSEBUTTONS | IDCMP_MOUSEMOVE | BUTTONIDCMP | IDCMP_REFRESHWINDOW | IDCMP_MENUPICK,
  247.                                                     WA_Gadgets,                glist,
  248.                                                     WA_CustomScreen,    scr,
  249.                                                     TAG_DONE,                    0))
  250.     {
  251.         /* If window opened, set clip region */
  252.         if(setClipInternal(win))
  253.         {
  254.             /* Attach menu strip to window */
  255.             if(SetMenuStrip(win, menustrip))
  256.             {
  257.                 /* Let GadTools refresh its bits of the window */
  258.                 GT_RefreshWindow(win, NULL);
  259.                 /* Now handle messages */
  260.                 handleIDCMP(win);
  261.                 /* Remove menu strip */
  262.                 ClearMenuStrip(win);
  263.             }
  264.             else
  265.                 printf("Error: could not attach menus to window\n");
  266.             removeClip(win);    
  267.         }
  268.         else
  269.             printf("Error: could not set clip region on window\n");
  270.         CloseWindow(win);
  271.     }
  272.     else
  273.         printf("Error: could not open window\n");
  274. }
  275.  
  276. /* Our message handling code */
  277. void handleIDCMP(struct Window* win)
  278. {
  279.     char* text = "Hello World!";
  280.     int going = TRUE;
  281.     int drawing = FALSE;
  282.     setFgPen(win, MYINITPEN);
  283.     /* Set the drawing mode to draw only the foreground of text, not the background */
  284.     SetDrMd(win->RPort, JAM1);
  285.     while(going)
  286.     {
  287.         struct IntuiMessage* intuimsg;
  288.         /* Wait for messages to arrive */
  289.         WaitPort(win->UserPort);
  290.         /* Messages have arrived: loop through all of them */
  291.         while(intuimsg = GT_GetIMsg(win->UserPort))
  292.         {
  293.             /* Act on this message... */
  294.             switch(intuimsg->Class)
  295.             {
  296.             case IDCMP_MOUSEBUTTONS:
  297.                 switch(intuimsg->Code)
  298.                 {
  299.                 case SELECTDOWN:
  300.                     drawing = TRUE;
  301.                     break;
  302.                 case SELECTUP:
  303.                     drawing = FALSE;
  304.                     break;
  305.                 }
  306.                 /* break; omitted so we draw on click, too */
  307.             case IDCMP_MOUSEMOVE:
  308.                 /* Don't draw on top gap which holds gadgets */
  309.                 if(drawing && intuimsg->MouseY > win->BorderTop+MYTOPGAP)
  310.                 {
  311.                     Move(win->RPort, intuimsg->MouseX, intuimsg->MouseY);
  312.                     Text(win->RPort, text, strlen(text));
  313.                 }
  314.                 break;
  315.             case IDCMP_CLOSEWINDOW:
  316.                 going = FALSE;
  317.                 break;
  318.             case IDCMP_REFRESHWINDOW:
  319.                 /* You *MUST* remember to ask for and handle these refresh messages */
  320.                 GT_BeginRefresh(win);
  321.                 GT_EndRefresh(win, TRUE);
  322.                 break;
  323.             case IDCMP_GADGETUP:
  324.                 doGadgetUp(win, intuimsg);
  325.                 break;
  326.             case IDCMP_MENUPICK:
  327.                 going = doMenuPick(win, intuimsg);
  328.                 break;
  329.             }
  330.             /* Reply when finished with message */
  331.             GT_ReplyIMsg(intuimsg);
  332.         }
  333.     }
  334. }
  335.  
  336. /* Set foreground pen of window */
  337. void setFgPen(struct Window* win, int value)
  338. {
  339.     /* Wrap when reached the end of the palette gadget's colours */
  340.     pen = value % (1<<MYPAL_DEPTH);
  341.     SetAPen(win->RPort, pen);
  342.     /* If the palette gadget has been made, update it with new pen value */
  343.     if(palgad)
  344.         GT_SetGadgetAttrs(palgad, win, NULL, GTPA_Color, pen, TAG_DONE);
  345. }
  346.  
  347. /* Process IDCMP_GADGETUP event */
  348. void doGadgetUp(struct Window* win, struct IntuiMessage* intuimsg)
  349. {
  350.     struct Gadget* gad = (struct Gadget*)(intuimsg->IAddress);
  351.     switch(gad->GadgetID)
  352.     {
  353.     case MYBUT_ID:
  354.         /* Our button was clicked!  Set foreground to next pen colour */
  355.         setFgPen(win, pen+1);
  356.         break;
  357.     case MYPAL_ID:
  358.         /* Our palette gadget was clicked!  Set foreground to gadget colour */
  359.         setFgPen(win, intuimsg->Code);
  360.         break;
  361.     }
  362. }
  363.  
  364. /* Process IDCMP_MENUPICK event */
  365. int doMenuPick(struct Window* win, struct IntuiMessage* intuimsg)
  366. {
  367.     UWORD menuCode, menuNumber, itemNumber;
  368.     /* Loop over all the menu selections in the menu code */
  369.     for(menuCode = intuimsg->Code;
  370.             menuCode != MENUNULL;
  371.             menuCode = ItemAddress(win->MenuStrip, menuCode)->NextSelect)
  372.     {
  373.         /* Extract the menu number and menu item number from the menu code */
  374.         menuNumber = MENUNUM(menuCode);
  375.         itemNumber = ITEMNUM(menuCode);
  376.         /* Now decide what to do based on what menu item was selected */
  377.         switch(menuNumber)
  378.         {
  379.         case 0:  /* Project menu */
  380.             /* Only one item: Quit */
  381.             if(itemNumber == 0)
  382.                 return FALSE;  /* Stop going */
  383.             break;
  384.         case 1:  /* Pen menu */
  385.             switch(itemNumber)
  386.             {
  387.             case 0:  /* Next */
  388.                 setFgPen(win, pen+1);
  389.                 break;
  390.             case 1:  /* Prev */
  391.                 setFgPen(win, pen-1);
  392.                 break;
  393.             case 3:  /* Reset (item 2 is the bar!) */
  394.                 setFgPen(win, MYINITPEN);
  395.                 break;
  396.             }
  397.             break;
  398.         }
  399.     }
  400.     /* Keep going */
  401.     return TRUE;
  402. }
  403.